package pl.edu.agh.ssm.monitor.net;

import java.net.InetAddress;

/**
 * Class contains informations which allows to decide
 * if listener is interested on receive data packet.
 * @author Tomasz Jadczyk
 *
 */
public class PacketFilter {

//	public static String ALL_PORTS = "\\d{1,5}"; //1 to 5 digit number
//	public static String ALL_IP_ADDRESSES = "\\d\\d\\d.\\d\\d\\d.\\d\\d\\d.\\d\\d\\d" ; //all addresses
	
	private int packetPort;
	
	private int lowPort = 0;
	private int highPort = 0;
	private String address = null;
	private String sourceAddress = null;
	private int sourcePort = 0;
	/*
	 * IF packetPort == 0 it means ALL_PORTS, 
	 * packetReceiverAddress == null it means ALL_IP_ADDRESSES
	 */
	public PacketFilter(int packetPort, String address) {
		this.packetPort = packetPort;
		this.address = address;
	}
	
	public PacketFilter() {
		
	}
	
	public void setAddress(String address) {
		this.address = address;
	}
	
	public void setPort(int port) {
		this.lowPort = port;
		this.highPort = port;
	}
	
	public void setPortRange(int lowPort, int highPort) {
		this.lowPort = lowPort;
		this.highPort = highPort;
	}
	
	public int getLowPort() {
		return lowPort;
	}

	public int getHighPort() {
		return highPort;
	}

	public String getAddress() {
		return address;
	}
	
	public String getSourceAddress() {
		return sourceAddress;
	}

	public void setSourceAddress(String sourceAddress) {
		this.sourceAddress = sourceAddress;
	}

	public int getSourcePort() {
		return sourcePort;
	}

	public void setSourcePort(int sourcePort) {
		this.sourcePort = sourcePort;
	}

	public boolean matches(int port, InetAddress address, InetAddress sourceAddress, int sourcePort) {
		boolean addressMatches = true;
		boolean portMatches = true;
		
		if(this.address != null && !this.address.equalsIgnoreCase("") && address != null) {
			if(!this.address.equalsIgnoreCase(address.getHostAddress())) {
				addressMatches = false;
			}
		} 
		
		if(this.highPort > 0) {
			if(port < this.lowPort || port > this.highPort) {
				portMatches = false;
			}
		}
		
		if(this.sourceAddress != null && !this.sourceAddress.equalsIgnoreCase("")) {
			if(!this.sourceAddress.equalsIgnoreCase(sourceAddress.getHostAddress())) {
				addressMatches = false;
			}
		}
		
		if(this.sourcePort > 0) {
			if(this.sourcePort != sourcePort) {
				addressMatches = false;
			}
		}
		
		return addressMatches && portMatches;
	}
	
	public int getPacketPort() {
		return packetPort;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof PacketFilter) {
			PacketFilter p2 = (PacketFilter) obj;
			return this.getLowPort() == p2.getLowPort() &&
				this.getHighPort() == p2.getHighPort() &&
				this.getAddress().equalsIgnoreCase(p2.getAddress()
						);
		}
		return false;
	}
	
}
